/**
 * data structures for `exact-hash' calculation facilities
 * A. Shabanov, 2010
 */

#pragma once

#include <stddef.h>
#include <stdbool.h>
#include <limits.h>

typedef int                 ExHashInt;
#define EX_HASH_INT_MAX     INT_MAX

#define EX_HASH_ARR_SIZE    (256)


struct ExHashTable
{
    ExHashInt               arr[EX_HASH_ARR_SIZE];
    struct ExHashTable *    next;
};

/**
 * retrieves exact hash of the string given
 * starting search from the given table entry,
 * if the table sequence does not contain hash, EX_HASH_INT_MAX returned instead
 */
static inline ExHashInt ex_hash_table_get_sum(const char * str,
                                              size_t str_len,
                                              struct ExHashTable * etable)
{
    ExHashInt result = 0;
    size_t i;

    for (i = 0; i < str_len; ++i)
    {
        if (!etable)
        {
            result = EX_HASH_INT_MAX;
            break;
        }

        result += etable->arr[(unsigned char)str[i]];
        etable = etable->next;
    }

    return result;
}

#define BSEARCH_NS(name)        ex_hash_##name
#define BSEARCH_ARRAY_TYPE      ExHashInt *
#define BSEARCH_KEY_TYPE        ExHashInt
#define BSEARCH_3W_COMPARE(array, index, key) (key - array[index])
#include <templates/bsearch.h>


static inline bool ex_hash_sums_bsearch_contains(ExHashInt hash, ExHashInt * arr, size_t arr_size)
{
    return ex_hash_binary_search(arr, arr_size, hash);
}

